package com.paper.tiger.easy.rpc.center.common;

import com.paper.tiger.easy.rpc.core.RegisterData;
import com.paper.tiger.easy.rpc.core.Stub;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * [简要描述]:
 * [详细描述]:
 *
 * 一个服务名称，--- 对应多个channel ---  一个channel对应多个stub
 *
 * @author ZouHaiBo
 * @version 1.0, 2021/5/28 17:33
 * @since JDK 1.8
 */
public class ServerMap
{

    /**
     * 客户端关注的服务
     * key =(channelId) value= 存根集合
     */
    private static final Map<Channel, List<Stub>> clientFoucsStubMap = new HashMap<>();

    /**
     * key =(channelId) value= 存根集合
     */
    private static final Map<Channel, RegisterData> channelStubsMap = new HashMap<>();


    /**
     * 注册服务 ,如果没有进行添加，如果存在，删除原先的数据
     *
     * @param data
     * @param channel
     */
    public static void addChannel(Channel channel,RegisterData data)
    {
        channelStubsMap.put(channel,data);
    }

    /**
     * 删除服务,如果服务下线，删除本台机器的服务
     *
     * @param channel
     */
    public static void removeChannel(Channel channel)
    {
        channelStubsMap.remove(channel);
    }

    public static RegisterData getRegisterData(Channel channel)
    {
        return channelStubsMap.get(channel);
    }

    public static List<Stub> listByInterfaceNames(List<String> interfaceNames)
    {

        List<Stub> result = new ArrayList<>();

        channelStubsMap.forEach((channel,data)->{

            List<Stub> list = data.getList();

            for (Stub stub : list)
            {
                if (interfaceNames.contains(stub.getInterfaceClass())){
                    result.add(stub);
                }
            }

        });

        return result;
    }

    /**
     *  // 客户端 关注什么服务
     * @param ctx
     * @param list
     */
    public static void focusServer(ChannelHandlerContext ctx, List<Stub> list)
    {
        clientFoucsStubMap.put(ctx.channel(),list);
    }

    /**
     * 根据注册接口查询 那些 channel 关注
     * @param list
     * @return
     */
    public static List<Channel> selectChannels(List<Stub> list)
    {
        List<Channel> channels = new ArrayList<>();

        List<String> interfaceNames = list.stream().map(e -> e.getInterfaceClass()).collect(Collectors.toList());
        clientFoucsStubMap.forEach((channel,stubs)->{

            for (Stub stub : stubs)
            {
                if (interfaceNames.contains(stub.getInterfaceClass())){
                    channels.add(channel);
                    break;
                }
            }

        });
        return channels;

    }
}
